/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controller;

import com.sun.faces.facelets.tag.jsf.core.EventHandler;
import java.io.StringReader;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.xml.crypto.dsig.TransformException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import model.FileList;
import org.primefaces.event.FileUploadEvent;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

/**
 *
 * @author HOANG ANH
 */
@ManagedBean
@SessionScoped
public class XPathController {

    @ManagedProperty(value = "#{fileList}")
    private FileList fileList;
    private String xmlFile = "";
    private String xPathExpression = "";
    private String result = "output result";
    private boolean ready = false;
    private String returnType = "Node";

    public FileList getFileList() {
        return fileList;
    }

    public void setFileList(FileList fileList) {
        this.fileList = fileList;
    }

    public String getxPathExpression() {
        return xPathExpression;
    }

    public void setxPathExpression(String xPathExpression) {
        this.xPathExpression = xPathExpression;
    }

    public String getReturnType() {
        return returnType;
    }

    public void setReturnType(String returnType) {
        this.returnType = returnType;
    }

    public boolean isReady() {
        if (xmlFile.equals("")) {
            ready = false;
        } else {
            ready = true;
        }
        return ready;
    }

    public void setReady(boolean ready) {
        this.ready = ready;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public String getXmlFile() {
        return xmlFile;
    }

    public String getXmlContent() {
        return fileList.getXmlList().get(xmlFile);
    }

    public void setXmlFile(String xmlFile) {
        this.xmlFile = xmlFile;
    }

    public void uploadFileHandler(FileUploadEvent event) {
        xmlFile = event.getFile().getFileName();
        String content = new String(event.getFile().getContents());
        Map<String, String> map = fileList.getXmlList();
        map.put(xmlFile, content);
    }

    public void execute() {
        try {
            XPath xPath = XPathFactory.newInstance().newXPath();
            InputSource source = new InputSource(new StringReader(getXmlContent()));
            Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source);

            if (returnType.equals("String")) {

                result = xPath.evaluate(xPathExpression, dom);

            } else if (returnType.equals("Boolean")) {
                result = String.valueOf(xPath.evaluate(xPathExpression, dom, XPathConstants.BOOLEAN));
            } else if (returnType.equals("Numberic")) {
                result = String.valueOf(xPath.evaluate(xPathExpression, dom, XPathConstants.NUMBER));
            } else if (returnType.equals("Node")) {
                Node node = (Node) xPath.evaluate(xPathExpression, dom, XPathConstants.NODE);
                result = "Node Name : " + node.getNodeName() + "<br/>";
                result += "Node Value : " + node.getNodeValue() + "<br/>";
                result += "Text Content : " + node.getTextContent() + "<br/>";
                if (node.getAttributes() == null) {
                    result += "Number of Attribute : 0 <br/>";
                } else {
                    result += "Number of Attribute : " + node.getAttributes().getLength() + "<br/>";
                }
                result += "Number of Child : " + node.getChildNodes().getLength() + "<br/>";
            } else {
                NodeList nodelist = (NodeList) xPath.evaluate(xPathExpression, dom, XPathConstants.NODESET);
                result = "Total : " + nodelist.getLength() + " node(s)<br/>";
                result += "----------------------------------------<br/>";
                for (int i = 0; i < nodelist.getLength(); i++) {
                    Node node = nodelist.item(i);
                    result += "Node number " + (i + 1) + "<br/>";
                    result += "Node Name : " + node.getNodeName() + "<br/>";
                    result += "Node Value : " + node.getNodeValue() + "<br/>";
                    result += "Text Content : " + node.getTextContent() + "<br/>";
                    if (node.getAttributes() == null) {
                        result += "Number of Attribute : 0 <br/>";
                    } else {
                        result += "Number of Attribute : " + node.getAttributes().getLength() + "<br/>";
                    }
                    result += "Number of Child : " + node.getChildNodes().getLength() + "<br/>";
                    result += "----------------------------<br/>";

                }
            }
        } catch (XPathExpressionException ex) {
            ex.printStackTrace();
            result = "Error!";
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "XPath Error!", ex.getMessage());
            FacesContext.getCurrentInstance().addMessage(null, message);

        } catch (Exception ex) {
            ex.printStackTrace();
            result = "Error!";
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Other Error!", ex.getMessage());
            FacesContext.getCurrentInstance().addMessage(null, message);
        }
    }

    /** Creates a new instance of XPathController */
    public XPathController() {
    }
}
